/* Copyright (C) 2016-2017 HangZhou Zenzet Technology Co., Ltd.
 * All right reserved

 * File:lktcipher.h
 * Author:guojianchuan
 * Date:2017-06-09

 */

#ifndef CIPHER_H
#define CIPHER_H

#ifdef __cplusplus
extern "C" {
#endif

#define START_IDENTIFY              "%lkt!"
#define END_IDENTIFY                '%'

#define VERSION_0                   0
#define VERSION_1                   1
#define AES_256_CFB                 "AES-256-CFB"
#define START_IDENTIFY_OFFSET       0
#define START_IDENTIFY_LEN          5
#define VERSION_IDENTIFY_OFFSET     (START_IDENTIFY_OFFSET + START_IDENTIFY_LEN)
#define VERSION_IDENTIFY_LEN        2
#define KEYCRC_IDENTIFY_OFFSET      (VERSION_IDENTIFY_OFFSET + VERSION_IDENTIFY_LEN)
#define KEYCRC_IDENTIFY_LEN         2
#define MAPPINGID_IDENTIFY_OFFSET   (KEYCRC_IDENTIFY_OFFSET + KEYCRC_IDENTIFY_LEN)
#define MAPPINGID_IDENTIFY_LEN      4
#define CIPHERCRC_IDENTIFY_OFFSET   (MAPPINGID_IDENTIFY_OFFSET + MAPPINGID_IDENTIFY_LEN)
#define CIPHERCRC_IDENTIFY_LEN      2
#define CIPHER_TEXT_IDENTIFY_OFFSET (CIPHERCRC_IDENTIFY_OFFSET + CIPHERCRC_IDENTIFY_LEN)
#define END_IDENTIFY_LEN            1
#define LKT_FORMAT_LEN              (CIPHERCRC_IDENTIFY_OFFSET + CIPHERCRC_IDENTIFY_LEN + END_IDENTIFY_LEN)

/* Declare : Macro/Struct/Enum/Union */
/**
* @Enum: CIPHER_MODE_E
* @Author: guojianchuan/max
* @Date: 2017-06-09
* @Description: 加密/解密类型
*/
typedef enum tagCryptMode
{
    /* 解密 */
    DECRYPT = 0,

    /* 加密 */
    ENCRYPT = 1
}CRYPT_MODE_E;
    

/**
* @Struct: CIPHER_RSA_S
* @Author: guojianchuan/max
* @Date: 2017-06-26
* @Description: RSA结构
*/
typedef struct tagRSA
{
    /* 输入 */
    unsigned char *input;

    /* 输入长度 */
    int inlen;

    /* 输出(若是1024-RSA，则要求buffer大小至少128；若是2048-RSA，则要求buffer大小至少256 */
    unsigned char *output;

    /* 输出长度 */
    int outlen;

    /* 公钥/密钥 加密时设置为公钥，解密时设置为私钥 */
    unsigned char *pucKey;

    /* 密钥长度 */
    int keyLen;
}CIPHER_RSA_S;

/**
* @struct: CIPHER_AES_S 
* @Author: guojianchuan/max
* @Date: 2017-06-09
* @Description: AES结构
*/
typedef struct tagAES
{
    /* 算法名称 格式: 算法-位数-模式 eg:AES-128-CFB*/
    char algo[ALGO_NAME_LEN];

    /* 加解密 dec:DECRYPT enc:ENCRYPT */
    int mode;

    /* AES key */
    unsigned char *key;

    /* AES iv (ECB模式可以设置为NULL)*/
    unsigned char *iv;

    /* 输入 */
    unsigned char *input;

    /* 输入长度 */
    int inlen;

    /* 输出 */
    unsigned char *output;

    /* 输出长度 */
    int outlen;
}CIPHER_AES_S;

typedef struct tagCipherFomat
{
    int version;
    int  mappingid;
    char* key;                  /* base64 */
    unsigned char* cipherText;  /* base64 */
    int cipherLen;
    unsigned char* formated;
    int formatBufLen;
}CIPHER_FORMAT_S;


/* Declare: Function */
char* LKT_OpenSSLErrString (void);
int LKT_InitOpenSSL (void);
void LKT_ReleaseOpenSSL (void);
unsigned char* LKT_DecodeBase64 (unsigned char* in, int inlen, unsigned char* out, int *outlen);
unsigned char* LKT_ConvertToBase64(unsigned char *in, int inlen, unsigned char *out,  int *outlen, int newLine);
unsigned char* LKT_ConvertToHex(unsigned char *in, int inlen, unsigned char *out,  int *outlen);
int LKT_Digest(const char* algorithm, const char *in, unsigned char *out);
int LKT_Hmac(const char* algorithm, unsigned char *in, unsigned char* key, unsigned char *out, int *outlen);
int LKT_AESCrypt (CIPHER_AES_S *cipher);
int LKT_RSADecrypt (CIPHER_RSA_S *cipher);
int LKT_PBKDF2 (const char *pass, int passlen, const unsigned char *salt, 
                    int saltlen, int iter,int keylen, unsigned char *out);
void LKT_BuildCipherFormat (CIPHER_FORMAT_S *cipherFormat);
int LKT_CheckCipherFormat (const char* formatText, const char *key);
void LKT_GetCipherText (const char* formatText, char* cipherText);
int LKT_GetMappingID (const char* formatText);
int LKT_CheckStartIdentify (const char* field);

#ifdef __cplusplus
}
#endif

#endif
